package com.mzj.saas.mservice.task;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.haixiaoke.saas.repository.dto.ApartmentBillDTO;
import com.haixiaoke.saas.repository.dto.OrderReletDTO;
import com.haixiaoke.saas.repository.pojo.ApartmentBill;
import com.haixiaoke.saas.repository.pojo.Order;
import com.haixiaoke.saas.repository.pojo.OrderOperatingRecord;
import com.haixiaoke.saas.repository.pojo.OrderWechatPayRecord;
import com.haixiaoke.saas.repository.service.*;
import com.haixiaoke.saas.repository.util.GsonUtil;
import com.mzj.saas.commons.DateUtils;
import jodd.typeconverter.Convert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author Dell
 * @Date 2023/4/23
 **/
@Slf4j
@Service
public class WxPayCallBackService {

    @Autowired
    private IOrderService iOrderService;
    @Autowired
    private IOrderOperatingRecordService iOrderOperatingRecordService;
    @Autowired
    private IOrderWechatPayRecordService iOrderWechatPayRecordService;
    @Autowired
    private IOrderAmountItemService iOrderAmountItemService;
    @Autowired
    private IOrderLockService iOrderLockService;
    @Autowired
    private IHousingAllocationService iHousingAllocationService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IApartmentBillService apartmentBillService;


    @Transactional
    public void callBackOrder(Map<String, String> result) {
        if (result == null) {
            log.error("公寓小程序订单-支付-回调数据获取异常");
            return;
        }
        log.info("微信小程序支付---公寓回调解析的参数为：{}", GsonUtil.toJson(result));
        //存的是orgId-企业id
        String attach = result.get("attach");
        if (StringUtils.isBlank(attach)) {
            log.error("企业id为空 attach is null");
            return;
        }

        //公寓订单号
        String outTradeNo = result.get("outTradeNo");

        Order order = iOrderService.selectOrderById(outTradeNo);
        if (ObjectUtil.isEmpty(order)) {
            log.error("未找到公寓订单 outTradeNo={}", outTradeNo);
            return;
        }

        int totalAmount = Integer.parseInt((result.get("totalFee")));
        // 单位： 分
        //todo 金额校验暂时注释
        /*Integer pAmount = Convert.toInteger(NumberUtil.mul(order.getPriceAmounts().doubleValue(), 100));
        if (totalAmount.intValue() != pAmount) {
            log.error("公寓订单的计算金额和微信支付金额不匹配 orderId={},totalAmount={},cost={}",
                    outTradeNo, totalAmount, order.getPriceAmounts());
            return;
        }*/

        //添加订单回调记录
        OrderWechatPayRecord callbackRecord = new OrderWechatPayRecord(
                null, outTradeNo, result.get("transactionId"), (double) totalAmount,
                attach, result.get("returnCode"), result.get("returnMsg"), result.get("resultCode"), result.get("errCode"),
                result.get("errCodeDes"), result.get("appid"), result.get("mchId"), result.get("nonceStr"),
                DateUtils.convert(result.get("timeEnd"), DateUtils.FORMAT_14), result.get("timeEnd"));
        iOrderWechatPayRecordService.insertOrderWechatPayRecord(callbackRecord);

        Date updateTime = new Date();
        //订单还是未支付的状态的话，需要更改为已经支付
        if (Order.ORDER_STATE_UN_PAYMENT.equals(order.getOrderState())) {
            log.info("订单为未支付状态，需要修改为已支付状态，orderId：{}", outTradeNo);
            order.setOrderState(Order.ORDER_STATE_PAYMENT);
            order.setUpdateTime(updateTime);
            order.setUpdateBy(OrderOperatingRecord.OPERATING_BY);
            order.setPayTime(updateTime);
            order.setPayType(Order.PAY_TYPE_MINI_PROGRAM);
            int i = iOrderService.updateOrderState(order);
            if (i != 0) {
                //插入订单状态变更记录
                OrderOperatingRecord record = new OrderOperatingRecord();
                record.setOrderId(outTradeNo);
                record.setOrderSourceState(Order.ORDER_STATE_UN_PAYMENT);
                record.setOrderState(Order.ORDER_STATE_PAYMENT);
                record.setRemark(OrderOperatingRecord.RECORD_REMARK_PAYMENT);
                record.setOperatingTime(updateTime);
                record.setOperatingBy(OrderOperatingRecord.OPERATING_BY);
                iOrderOperatingRecordService.insertOrderOperatingRecord(record);
                //删除缓存订单数据
                redisTemplate.delete(Order.REDIS_ORDER_KEY_LOCK + outTradeNo);
            } else {
                log.info("小程序支付回调--公寓订单状态修改失败，resultInt：{}，Order：{}", i, order);
            }
        }
    }

    @Transactional
    public void callBackReletOrder(Map<String, String> result) {
        if (result == null) {
            log.error("公寓小程序订单-支付-回调数据获取异常");
            return;
        }
        log.info("微信小程序支付---公寓回调解析的参数为：{}", GsonUtil.toJson(result));
        //存的是orgId-企业id
        String attach = result.get("attach");
        if (StringUtils.isBlank(attach)) {
            log.error("企业id为空 attach is null");
            return;
        }

        //公寓订单号 outTradeNo为续租单号，数据格式为 orderId + "_" + reletNum
        String outTradeNo = result.get("outTradeNo");
        String[] split = outTradeNo.split("_");

        Order order = iOrderService.selectOrderById(split[0]);
        if (ObjectUtil.isEmpty(order)) {
            log.error("未找到公寓订单 outTradeNo={}", outTradeNo);
            return;
        }

        Object o = redisTemplate.opsForValue().get(Order.REDIS_ORDER_KEY_RELET + outTradeNo);
        OrderReletDTO reletDTO = JSONObject.parseObject(JSONObject.toJSONString(o), OrderReletDTO.class);

        int totalAmount = Integer.parseInt((result.get("totalFee")));
        // 单位： 分
        //todo 金额校验暂时注释
        Integer pAmount = Convert.toInteger(NumberUtil.mul(reletDTO.getOrderAmountItemList().get(0).getTotalPrice().doubleValue(), 100));
        /*if (totalAmount != pAmount) {
            log.error("公寓订单的计算金额和微信支付金额不匹配 orderId={},totalAmount={},cost={}",
                    outTradeNo, totalAmount, order.getPriceAmounts());
            return;
        }*/

        //添加订单回调记录
        OrderWechatPayRecord callbackRecord = new OrderWechatPayRecord(
                null, outTradeNo, result.get("transactionId"), (double) totalAmount,
                attach, result.get("returnCode"), result.get("returnMsg"), result.get("resultCode"), result.get("errCode"),
                result.get("errCodeDes"), result.get("appid"), result.get("mchId"), result.get("nonceStr"),
                DateUtils.convert(result.get("timeEnd"), DateUtils.FORMAT_14), result.get("timeEnd"));
        iOrderWechatPayRecordService.insertOrderWechatPayRecord(callbackRecord);


        //订单状态修改
        iOrderService.updateReLetOrder(reletDTO.getOrder());
        //订单金额计算项目
        iOrderAmountItemService.insertBatchOrderAmountItem(reletDTO.getOrderAmountItemList());
        //添加订单操作记录
        iOrderOperatingRecordService.insertOrderOperatingRecord(reletDTO.getOrderOperatingRecord());
        //修改锁单记录信息
        iOrderLockService.updateOrderLockByOrderId(reletDTO.getOrderLock());
        //删除缓存数据
        redisTemplate.delete(Order.REDIS_ORDER_KEY_RELET + outTradeNo);

    }

    @Transactional
    public void callBackBill(Map<String, String> result) {
        if (result == null) {
            log.error("公寓小程序账单-支付-回调数据获取异常");
            return;
        }

        log.info("微信小程序支付---公寓回调解析的参数为：{}", GsonUtil.toJson(result));
        String outTradeNo = result.get("outTradeNo");
        if (StringUtils.isBlank(outTradeNo)) {
            log.error("订单id为空 attach is null");
            return;
        }

        Object object = redisTemplate.opsForValue().get(ApartmentBill.REDIS_BILL_KEY + outTradeNo);
        if (object == null) {
            log.error("未找到该订单 outTradeNo:{}",outTradeNo);
            return;
        }
        ApartmentBillDTO dto = JSONObject.parseObject(object.toString(), ApartmentBillDTO.class);
        List<String> billIds = dto.getBillIds();
        List<ApartmentBill> apartmentBills = apartmentBillService.selectApartmentBillByBillIds(billIds);

        //校验支付金额是否一致
        double billCost = apartmentBills.stream().mapToDouble(ApartmentBill::getBillCost).sum();
        Integer cost = Convert.toInteger(NumberUtil.mul(billCost, 100));
        int totalAmount = Integer.parseInt((result.get("totalFee")));
        // if (cost != totalAmount){
        //     log.error("公寓账单的计算金额和微信支付金额不匹配 outTradeNo={},totalAmount={},billCost={}",
        //             outTradeNo, totalAmount, billCost);
        //     return;
        // }

        for (ApartmentBill apartmentBill : apartmentBills) {
            apartmentBill.setPayStatus(ApartmentBill.PAY_STATUS_YES);
            apartmentBill.setPayTime(new Date());
            apartmentBillService.updateApartmentBill(apartmentBill);
        }

        //删除缓存账单信息
        redisTemplate.delete(ApartmentBill.REDIS_BILL_KEY + outTradeNo);

    }
}
